#pragma once
#ifdef __cplusplus
extern "C" {
#endif
	/*
	* Divert address.
	*/
	typedef struct
	{
		INT64  Timestamp;                   /* Packet's timestamp. */
		UINT32 IfIdx;                       /* Packet's interface index. */
		UINT32 SubIfIdx;                    /* Packet's sub-interface index. */
		UINT8  Direction : 1;                 /* Packet's direction. */
		UINT8  Loopback : 1;                  /* Packet is loopback? */
		UINT8  Impostor : 1;                  /* Packet is impostor? */
		UINT8  PseudoIPChecksum : 1;          /* Packet has pseudo IPv4 checksum? */
		UINT8  PseudoTCPChecksum : 1;         /* Packet has pseudo TCP checksum? */
		UINT8  PseudoUDPChecksum : 1;         /* Packet has pseudo UDP checksum? */
		UINT8  Reserved : 2;
	} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS;

#define WINDIVERT_DIRECTION_OUTBOUND    0
#define WINDIVERT_DIRECTION_INBOUND     1

	/*
	* Divert layers.
	*/
	typedef enum
	{
		WINDIVERT_LAYER_NETWORK = 0,        /* Network layer. */
		WINDIVERT_LAYER_NETWORK_FORWARD = 1 /* Network layer (forwarded packets) */
	} WINDIVERT_LAYER, *PWINDIVERT_LAYER;

	/*
	* Divert flags.
	*/
#define WINDIVERT_FLAG_SNIFF            1
#define WINDIVERT_FLAG_DROP             2
#define WINDIVERT_FLAG_DEBUG            4

	/*
	* Divert parameters.
	*/
	typedef enum
	{
		WINDIVERT_PARAM_QUEUE_LEN = 0,     /* Packet queue length. */
		WINDIVERT_PARAM_QUEUE_TIME = 1,     /* Packet queue time. */
		WINDIVERT_PARAM_QUEUE_SIZE = 2      /* Packet queue size. */
	} WINDIVERT_PARAM, *PWINDIVERT_PARAM;
#define WINDIVERT_PARAM_MAX             WINDIVERT_PARAM_QUEUE_SIZE
	HANDLE WinDivertOpen(
		__in        const char *filter,
		__in        WINDIVERT_LAYER layer,
		__in        INT16 priority,
		__in        UINT64 flags);
	BOOL WinDivertRecv(
		__in        HANDLE handle,
		__out       PVOID pPacket,
		__in        UINT packetLen,
		__out_opt   PWINDIVERT_ADDRESS pAddr,
		__out_opt   UINT *readLen);
	BOOL WinDivertSend(
		__in        HANDLE handle,
		__in        PVOID pPacket,
		__in        UINT packetLen,
		__in        PWINDIVERT_ADDRESS pAddr,
		__out_opt   UINT *writeLen);
	BOOL WinDivertClose(
		__in        HANDLE handle);
	BOOL WinDivertSetParam(
		__in        HANDLE handle,
		__in        WINDIVERT_PARAM param,
		__in        UINT64 value);


#ifdef __cplusplus
}
#endif